#include <cJSON.h>
#include "ohos_init.h"
#include "los_task.h"
#include "oc_mqtt.h"
#include "e53_intelligent_agriculture.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h> 
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <endian.h>
#include <fcntl.h>
#include <math.h>
#include "lz_hardware.h"
#include <stdio.h>
#include "cmsis_os2.h"
#include "los_task.h"
#include "lz_hardware.h"
#include "lwip/tcp.h"
#include "lwip/ip_addr.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/stats.h"
#include "lwip/inet_chksum.h"
#include <math.h>
 

#define UART_ID                 0
#define STRING_MAXSIZE          128
#define MSG_QUEUE_LENGTH                256
#define BUFFER_LEN                      100
#define CLIENT_ID                       "651e59fd02c946447756b946_fjpsc_0_0_2023100514"
#define USERNAME                        "651e59fd02c946447756b946_fjpsc"
#define PASSWORD                        "42fc36f48fa06766780e407a9b42c61dd3255394059c8a6ba38fbebf51ccef66"
#define OC_SERVER_IP   "116.62.81.138"
#define SERVER_PORT 80
#define N 50

/* 定义测量土壤光照的ADC的通道号 */
#define ADC_CHANNEL_illumination 3

/* 定义测量土壤湿度的ADC的通道号 */
#define ADC_CHANNEL_moisture 4

/*光照最弱时检测的电压值*/
#define soil_illumination_min 1024.000

/*光照最强时检测的电压值*/
#define soil_illumination_max 1.000

/*湿度为0时ADC获取的电压值*/
#define soil_moisture_min 3.297

/*湿度为100%时ADC获取的电压值*/
#define soil_moisture_max 1.300



#define GPIO_TEST    GPIO0_PA2//GPIO的引脚号，为开发板上的GPIO1

/* 定义ADC初始化的结构体 */
static DevIo m_adcKey = {
    .isr =   {.gpio = INVALID_GPIO},
    .rst =   {.gpio = INVALID_GPIO},
    .ctrl1 = {.gpio = GPIO0_PC3, .func = MUX_FUNC1, .type = PULL_NONE, .drv = DRIVE_KEEP, .dir = LZGPIO_DIR_IN, .val = LZGPIO_LEVEL_KEEP},
    .ctrl2 = {.gpio = INVALID_GPIO},
};


/*存储光照的结构体*/
typedef struct
{
     char soil_illumination[N];
     char soil_moisture[N];
     char soil_temperature[N];
}soil;

soil id;

float voltage_illumination;
float voltage_moisture;

typedef struct  {
	char id[N];
	char name[N];
	char country[N];
	char path[N];
	char timezone[N];
	char timezone_offset[N];
}Location;

typedef struct  {
	char text[N];
	char code[N];
	char temperature[N];
	char feels_like[N];
	char pressure[N];
	char humidity[N];
	char visibility[N];
	char wind_direction[N];
	char wind_direction_degree[N];
	char wind_speed[N];
	char wind_scale[N];
	char clouds[N];
	char dew_point[N];
}Now;

Now ndata;

typedef struct  {
	char last_update[N];
}Last_update;

void get_weather(void);//发送http请求得到天气的json数据
void task_weather();//创建获取天气的任务
void output_data(const char* json);//得到解析完全的天气数据并打印



typedef struct
{
    double lum;//光照
    double temp;//空气温度
    double hum;//空气湿度
    double stemp;//土壤温度
    double shum;//土壤湿度
} ia_report_t;

typedef struct
{
    en_msg_type_t msg_type;
    cmd_t cmd;
    ia_report_t report;
} ia_msg_t;

typedef struct
{
    int connected;
    int pump;
    int fan;
} ia_status_t;

typedef struct
 {
    struct tm m_t;
    char time[64];
} DATA;


DATA date1;

static unsigned int m_ia_MsgQueue;
static ia_status_t m_app_status;

static int flag=0;

static int flag1=0;
static int kai=0;
static int kai1=0;

//上报智慧农业模块数据到华为云上
void ia_deal_report_msg(ia_report_t *report)
{
    oc_mqtt_profile_service_t service;
    oc_mqtt_profile_kv_t temperature;
    oc_mqtt_profile_kv_t humidity;
    oc_mqtt_profile_kv_t luminance;
    oc_mqtt_profile_kv_t led;
    oc_mqtt_profile_kv_t motor;
    oc_mqtt_profile_kv_t weather;
    oc_mqtt_profile_kv_t shumidity;
    oc_mqtt_profile_kv_t stemperature;

    printf("上传云端中\n");
    service.event_time = NULL;
    service.service_id = "智慧农业";
    service.service_property = &temperature;
    service.nxt = NULL;

    temperature.key = "空气温度";
    temperature.value = &report->temp;
    temperature.type = EN_OC_MQTT_PROFILE_VALUE_FLOAT;
    temperature.nxt = &humidity;

    humidity.key = "空气湿度";
    humidity.value = &report->hum;
    humidity.type = EN_OC_MQTT_PROFILE_VALUE_FLOAT;
    humidity.nxt = &luminance;

    luminance.key = "光照强度";
    luminance.value = id.soil_illumination;
    luminance.type = EN_OC_MQTT_PROFILE_VALUE_STRING;
    luminance.nxt = &led;

    led.key = "水泵状态";
    led.value = m_app_status.pump ? "开" : "关";
    led.type = EN_OC_MQTT_PROFILE_VALUE_STRING;
    led.nxt = &motor;

    motor.key = "风扇状态";
    motor.value = m_app_status.fan ? "开" : "关";
    motor.type = EN_OC_MQTT_PROFILE_VALUE_STRING;
    motor.nxt = &weather;

    weather.key="天气状况";
    weather.value = ndata.text;
    weather.type = EN_OC_MQTT_PROFILE_VALUE_STRING;
    weather.nxt = &shumidity;

    shumidity.key="土壤湿度";
    shumidity.value=id.soil_moisture;
    shumidity.type=EN_OC_MQTT_PROFILE_VALUE_STRING;
    shumidity.nxt = &stemperature;

    stemperature.key="土壤温度";
    stemperature.value=id.soil_temperature;
    stemperature.type=EN_OC_MQTT_PROFILE_VALUE_STRING;
    stemperature.nxt = NULL;

    oc_mqtt_profile_propertyreport(USERNAME, &service);
}

//华为云命令处理回调函数
void ia_cmd_response_callback(uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size)
{
    printf("回调函数执行\n");
    ia_msg_t *app_msg = NULL;
    int ret = 0;

    app_msg = malloc(sizeof(ia_msg_t));
    if (app_msg == NULL)
    {
        printf("malloc msg fail");
        return;
    }
    app_msg->msg_type = en_msg_cmd;
    app_msg->cmd.payload = (char *)recv_data;

    printf("recv data is %.*s", recv_size, recv_data);
    if (LOS_OK != LOS_QueueWrite(m_ia_MsgQueue, (void *)app_msg, sizeof(ia_msg_t), 0))
    {
        printf("%s LOS_QueueWrite fail\n", __func__);
        free(recv_data);
        free(app_msg);
    }
    *resp_data = NULL;
    *resp_size = 0;
}

//处理华为云命令指针的函数
void ia_deal_cmd_msg(cmd_t *cmd)
{
    cJSON *obj_root;
    cJSON *obj_cmdname;
    cJSON *obj_paras;
    cJSON *obj_para;
    int cmdret = 1;
    oc_mqtt_profile_cmdresp_t cmdresp;

    obj_root = cJSON_Parse(cmd->payload);
    if (obj_root == NULL)
    {
        goto EXIT_JSONPARSE;
    }

    obj_cmdname = cJSON_GetObjectItem(obj_root, "command_name");
    if (obj_cmdname == NULL)
    {
        goto EXIT;
    }
    if (0 == strcmp(cJSON_GetStringValue(obj_cmdname), "水泵控制"))
    {
        obj_paras = cJSON_GetObjectItem(obj_root, "paras");
        if (obj_paras == NULL)
        {
            goto EXIT;
        }
        obj_para = cJSON_GetObjectItem(obj_paras, "Pump");
        if (obj_para == NULL)
        {
            goto EXIT;
        }
        if (0 == strcmp(cJSON_GetStringValue(obj_para), "ON"))
        {
            m_app_status.pump = 1;
            kai = 1;
            printf("Pump On\n");
        }
        if (0 == strcmp(cJSON_GetStringValue(obj_para), "OFF"))
        {
            m_app_status.pump = 0;
            kai = 0;
            printf("Pump Off\n");
        }
        cmdret = 0;
    }
    else if (0 == strcmp(cJSON_GetStringValue(obj_cmdname), "风扇控制"))
    {
        obj_paras = cJSON_GetObjectItem(obj_root, "Paras");
        if (obj_paras == NULL)
        {
            goto EXIT;
        }
        obj_para = cJSON_GetObjectItem(obj_paras, "Fan");
        if (obj_para == NULL)
        {
            goto EXIT;
        }
        if (0 == strcmp(cJSON_GetStringValue(obj_para), "ON"))
        {
            m_app_status.fan = 1;
            kai1 = 1;
            printf("Fan On\n");
        }
        if (0 == strcmp(cJSON_GetStringValue(obj_para), "OFF"))
        {
            m_app_status.fan = 0;
            kai1 = 0;
            // motor_set_status(OFF);
            printf("Fan Off\n");
        }
        cmdret = 0;
    }

EXIT:
    cJSON_Delete(obj_root);
EXIT_JSONPARSE:
    cmdresp.paras = NULL;
    cmdresp.request_id = cmd->request_id;
    cmdresp.ret_code = cmdret;
    cmdresp.ret_name = NULL;

    oc_mqtt_profile_cmdresp(NULL, &cmdresp);
}


void iot_cloud_ia_thread()
{
    ia_msg_t *app_msg = NULL;
    unsigned int addr;
    int ret;

    SetWifiModeOn();
    flag=1;

    device_info_init(CLIENT_ID, USERNAME, PASSWORD);
    ret = oc_mqtt_init();
    if (ret != LOS_OK)
    {
        printf("oc_mqtt_init fail ret:%d\n", ret);
    }
    // oc_set_cmd_rsp_cb(ia_cmd_response_callback);
    

    while (1)
    {
        oc_set_cmd_rsp_cb(ia_cmd_response_callback);
        ret = LOS_QueueRead(m_ia_MsgQueue, (void *)&addr, BUFFER_LEN, LOS_WAIT_FOREVER);
        if (ret == LOS_OK)
        {
            app_msg = addr;
            switch (app_msg->msg_type)
            {
                case en_msg_cmd:
                    ia_deal_cmd_msg(&app_msg->cmd);
                    break;
                case en_msg_report:
                    ia_deal_report_msg(&app_msg->report);
                    break;
                default:
                    break;
            }
            free(app_msg);
            app_msg = NULL;
        }
        else
        {
            LOS_Msleep(1000);
        }
    }
}

//E53函数
void e53_ia_thread()
{
    ia_msg_t *app_msg = NULL;
    // e53_ia_data_t data;

    // e53_ia_init();
    while(flag==0)
    {
        sleep(3);
        printf("e53 wait3s\n");
    }


    while (1)
    {
        // e53_ia_read_data(&data);
        // adc_process();
        get_weather();
        // get_internat_server_thread();
        // get_time();
        // printf("Luminance:%.2f temperature:%.2f humidity:%.2f\n", data.luminance, data.temperature, data.humidity);
        

        app_msg = malloc(sizeof(ia_msg_t));
        if (app_msg != NULL)
        {
            app_msg->msg_type = en_msg_report;
            app_msg->report.hum = atof(ndata.humidity);
            app_msg->report.temp = atof(ndata.temperature);
            app_msg->report.lum = voltage_illumination;
            app_msg->report.shum= voltage_moisture;
            // printf("空气温度：%.2f,空气湿度：%.2f,光照强度:%.2f,土壤湿度：%.2f\n",app_msg->report.temp,app_msg->report.hum,app_msg->report.lum,app_msg->report.shum);
            printf("空气温度：%.2f,空气湿度：%.2f,光照强度:%s,土壤湿度：%s,土壤温度：%s\n",app_msg->report.temp,app_msg->report.hum,id.soil_illumination,id.soil_moisture,id.soil_temperature);
            
            if (LOS_QueueWrite(m_ia_MsgQueue, (void *)app_msg, sizeof(ia_msg_t), LOS_WAIT_FOREVER) != LOS_OK)
            {
                printf("%s LOS_QueueWrite fail\n", __func__);
                free(app_msg);
            }
        }
        LOS_Msleep(5000);
    }
}


void get_weather(void) {
    uint8_t response[2048];
    memset(response, 0, sizeof (response));
    int sockfd, idx;
    int rv;
    const char* request = "GET https://api.seniverse.com/v3/weather/now.json?key=SRvdm5q9_eGzODYjI&location=nanping&language=zh-Hans&unit=c\r\n";
    // WifiConnect(CONFIG_WIFI_SSID, CONFIG_WIFI_PWD);

    
    // while(flag==0)
    // {
    //     sleep(3);
    //     printf("weather wait3s\n");
    // }

    

    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(80);
    if (inet_pton(AF_INET, "116.62.81.138", &serverAddr.sin_addr) <= 0) {
        printf("inet_pton failed!\r\n");
    }

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    // 尝试和目标主机建立连接，连接成功会返回0 ，失败返回 -1
    if (connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
        printf("connect failed!\r\n");
    }

    // 发送HTTP请求到天气服务器
    if (send(sockfd, request, strlen(request), 0) <0) 
        printf("send failed\n");
    else
        printf("send success\n");

    // 接收HTTP响应
    int len = recv(sockfd, response, sizeof(response), 0);
    if (len < 0) 
        printf("recv failed\n");
    printf("recv success\n");
    response[len] = '\0';

     printf("len is:%d\n", strlen(response));
        
    printf("\n");

    output_data(response);
    //weather_parse(response);
    // 关闭socket
    lwip_close(sockfd);
    // flag1=1;
    
    
}
//获取天气状况的函数
void output_data(const char* json) {

	Location ldata;
	
	Last_update last;
	cJSON* root = cJSON_Parse(json);
	if (root == NULL) {
		return;
	}
	cJSON* results = cJSON_GetObjectItem(root,"results");
	cJSON* item = cJSON_GetArrayItem(results,0);
	
	cJSON* location = cJSON_GetObjectItem(item,"location");
	cJSON* id = cJSON_GetObjectItem(location,"id");
	char* l_id = id->valuestring;
	snprintf(ldata.id,sizeof(ldata.id),l_id);
	cJSON* name = cJSON_GetObjectItem(location, "name");
	char* l_name = name->valuestring;
	snprintf(ldata.name,sizeof(ldata.name),l_name);
	cJSON* country = cJSON_GetObjectItem(location,"country");
	char* l_country = country->valuestring;
	snprintf(ldata.country,sizeof(ldata.country),l_country);
	cJSON* path = cJSON_GetObjectItem(location, "path");
	char* l_path = path->valuestring;
	snprintf(ldata.path,sizeof(ldata.path),l_path);
	cJSON* timezone = cJSON_GetObjectItem(location,"timezone");
	char* l_timezone = timezone->valuestring;
	snprintf(ldata.timezone, sizeof(ldata.timezone),l_timezone);
	cJSON* timezone_offset = cJSON_GetObjectItem(location,"timezone_offset");
	char* l_timezone_offset = timezone_offset->valuestring;
	snprintf(ldata.timezone_offset,sizeof(ldata.timezone_offset),l_timezone_offset);
	
	cJSON* now = cJSON_GetObjectItem(item, "now");
	cJSON* text = cJSON_GetObjectItem(now, "text");
	char* n_text = text->valuestring;
	snprintf(ndata.text, sizeof(ndata.text), n_text);
	cJSON* code = cJSON_GetObjectItem(now, "code");
	char* n_code = code->valuestring;
	snprintf(ndata.code,sizeof(ndata.code),n_code);
	cJSON* temperature = cJSON_GetObjectItem(now, "temperature");
	char* n_temperature = temperature->valuestring;
	snprintf(ndata.temperature, sizeof(ndata.temperature), n_temperature);
	cJSON* feels_like = cJSON_GetObjectItem(now,"feels_like");
	char* n_feels_like = feels_like->valuestring;
	snprintf(ndata.feels_like,sizeof(ndata.feels_like),n_feels_like);
	cJSON* pressure = cJSON_GetObjectItem(now,"pressure");
	char* n_pressure = pressure->valuestring;
	snprintf(ndata.pressure, sizeof(ndata.pressure), n_pressure);
	cJSON* humidity = cJSON_GetObjectItem(now, "humidity");
	char* n_humidity = humidity->valuestring;
	snprintf(ndata.humidity,sizeof(ndata.humidity),n_humidity);
	cJSON* visibility = cJSON_GetObjectItem(now,"visibility");
	char* n_visibility = visibility->valuestring;
	snprintf(ndata.visibility, sizeof(ndata.visibility), n_visibility);
	cJSON* wind_direction = cJSON_GetObjectItem(now, "wind_direction");
	char* n_wind_direction = wind_direction->valuestring;
	snprintf(ndata.wind_direction, sizeof(ndata.wind_direction), n_wind_direction);
	cJSON* wind_direction_degree = cJSON_GetObjectItem(now,"wind_direction_degree");
	char* n_wind_direction_degree = wind_direction_degree->valuestring;
	snprintf(ndata.wind_direction_degree, sizeof(ndata.wind_direction_degree), n_wind_direction_degree);
	cJSON* wind_speed = cJSON_GetObjectItem(now, "wind_speed");
	char* n_wind_speed = wind_speed->valuestring;
	snprintf(ndata.wind_speed,sizeof(ndata.wind_speed),n_wind_speed);
	cJSON* wind_scale = cJSON_GetObjectItem(now, "wind_scale");
	char* n_wind_scale = wind_scale->valuestring;
	snprintf(ndata.wind_scale,sizeof(ndata.wind_scale),n_wind_scale);
	cJSON* clouds = cJSON_GetObjectItem(now,"clouds");
	char* n_clouds = clouds->valuestring;
	snprintf(ndata.clouds,sizeof(ndata.clouds),n_clouds);
	cJSON* dew_point = cJSON_GetObjectItem(now, "dew_point");
	char* n_dew_point = dew_point->valuestring;
	snprintf(ndata.dew_point,sizeof(ndata.dew_point),n_dew_point);

	cJSON* last_update = cJSON_GetObjectItem(item,"last_update");
	char* l_last_update = last_update->valuestring;
	snprintf(last.last_update,sizeof(last.last_update),l_last_update);

	// printf("id:%s\r\n",ldata.id);
	// printf("name:%s\r\n",ldata.name);
	// printf("country:%s\r\n",ldata.country);
	printf("path:%s\r\n",ldata.path);
	// printf("timezone:%s\r\n",ldata.timezone);
	// printf("timezone_offset:%s\r\n",ldata.timezone_offset);
	printf("text:%s\r\n",ndata.text);
	// printf("code:%s\r\n",ndata.code);
	printf("temperature:%s\r\n",ndata.temperature);
	// printf("feels_like:%s\r\n",ndata.feels_like);
	// printf("pressure:%s\r\n",ndata.pressure);
	printf("humidity:%s\r\n",ndata.humidity);
	// printf("visibility:%s\r\n",ndata.visibility);
	// printf("wind_direction:%s\r\n",ndata.wind_direction);
	// printf("wind_direction_degree:%s\r\n",ndata.wind_direction_degree);
	// printf("wind_speed:%s\r\n",ndata.wind_speed);
	// printf("wind_scale:%s\r\n",ndata.wind_scale);
	// printf("clouds:%s\r\n",ndata.clouds);
	// printf("dew_point:%s\r\n",ndata.dew_point);
	// printf("last_update:%s\r\n",last.last_update);
}

/*初始化ADC*/
static unsigned int adc_dev_init()
{
    unsigned int ret = 0;
    uint32_t *pGrfSocCon29 = (uint32_t *)(0x41050000U + 0x274U);
    uint32_t ulValue;

    ret = DevIoInit(m_adcKey);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %s, %d: ADC Key IO Init fail\n", __FILE__, __func__, __LINE__);
        return __LINE__;
    }
    ret = LzSaradcInit();
    if (ret != LZ_HARDWARE_SUCCESS) {
        printf("%s, %s, %d: ADC Init fail\n", __FILE__, __func__, __LINE__);
        return __LINE__;
    }

    /* 设置saradc的电压信号，选择AVDD */
    ulValue = *pGrfSocCon29;
    ulValue &= ~(0x1 << 4);
    ulValue |= ((0x1 << 4) << 16);
    *pGrfSocCon29 = ulValue;
    
    return 0;
}


static float adc_get_voltage_illumination()
{
    unsigned int ret = LZ_HARDWARE_SUCCESS;
    unsigned int data = 0;

    ret = LzSaradcReadValue(ADC_CHANNEL_illumination, &data);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %s, %d: ADC Read Fail\n", __FILE__, __func__, __LINE__);
        return 0.0;
    }

    return (float)(data );
}


static float adc_get_voltage_moisture()
{
    unsigned int ret = LZ_HARDWARE_SUCCESS;
    unsigned int data = 0;

    ret = LzSaradcReadValue(ADC_CHANNEL_moisture, &data);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %s, %d: ADC Read Fail\n", __FILE__, __func__, __LINE__);
        return 0.0;
    }

    return (float)(data * 3.3 / 1024.0);
}




void adc_process()
{
    
    /* 初始化adc设备 */
    adc_dev_init();

    
    
    while (1)
    {
        /*获取电压值,进行百分比换算*/
        voltage_illumination = adc_get_voltage_illumination();
        voltage_illumination=((voltage_illumination-soil_illumination_min)/(soil_illumination_max-soil_illumination_min))*100;
		sprintf(id.soil_illumination,"%.2f%%",voltage_illumination);
        // printf("光照强度为：%s\n", id.soil_illumination);

        
	
        voltage_moisture = adc_get_voltage_moisture();
        voltage_moisture=((voltage_moisture-soil_moisture_min)/(soil_moisture_max-soil_moisture_min))*100;
        sprintf(id.soil_moisture,"%.2f%%",voltage_moisture);
        // printf("土壤湿度为:%s\n",id.soil_moisture);
	
        /* 睡眠5秒 */
        sleep(2);
    }
}

void gpio_process()
{
    unsigned int cur = 0;//初始化电平值为低电平
    LzGpioValue value = LZGPIO_LEVEL_LOW;
    double a=20.0;

    /* 初始化引脚为GPIO */
    LzGpioInit(GPIO_TEST);
    /* 引脚复用配置为GPIO */
    PinctrlSet(GPIO_TEST, MUX_FUNC0, PULL_KEEP, DRIVE_LEVEL0);

    while(flag==0)
    {
        sleep(3);
        printf("gpio1 wait3s\n");
    }

    while (1)
    {
        // printf("***************GPIO Example*************\r\n");
        // printf("Write GPIO\n");
        LzGpioSetDir(GPIO_TEST, LZGPIO_DIR_OUT);//设置GPIO口为输出电平模式
        
        if (a > voltage_moisture || kai== 1)
        {
            
            cur = 1;//电平值置为高电平
            LzGpioSetVal(GPIO_TEST, cur);//输出值函数
            m_app_status.pump = 1;
            LzGpioGetVal(GPIO_TEST, &value);//读取GPIO口的电平值
            // printf("\tgpio set %d => gpio get %d\n", cur, value);
            
            printf("打开水泵\n");
            

            
        }


        else
        {
            
            cur = 0;
            LzGpioSetVal(GPIO_TEST, cur);//输出值函数
            m_app_status.pump = 0;
            LzGpioGetVal(GPIO_TEST, &value);//读取GPIO口的电平值
            // printf("\tgpio set %d => gpio get %d\n", cur, value);
            
            // printf("关闭水泵\n");
            
        }
        sleep(2);
    }
   
}

// void get_internat_server_thread()
// {
    

   

//     int sockfd, n ,idx;
//     int now = -1, last = -1;
//     char send_buf[48] = {0};
//     uint8_t recv_buf[48];

//     // while(flag == 0)
//     // {
//     //     sleep(3);
//     //     printf("udp wait 3s\n");
//     // }

//     // 创建UDP套接字
//     sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    
//     if (sockfd < 0) {
//         printf("socket creation failed\n");
//         return -1;
        
//     }
    

    
//     // printf("第二.1步\n");
//     // int flags = fcntl(sockfd, F_GETFL);//获取套接字状态
//     // printf("第二步.2\n");
//     // if (flags < 0) {
//     //     printf("fcntl F_GETFL fail!!\n");
//     //     close(sockfd);
//     //     return -1;
        
//     // }
    
    
//     // printf("第三.1步\n");
//     // printf("%d\n",flags);
//     // int ret = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);// 将 socket设置为非阻塞模式
//     // printf("第三.2步\n");
//     // if (ret < 0 ) {
//     //     printf("fcntl F_SETFL O_NONBLOCK fail !!\n");
//     //     close(sockfd);
//     //     return -1;
//     // }

   
    

//     // 设置服务器地址
//     struct sockaddr_in serv_addr;
//     socklen_t send_addr_len = sizeof(serv_addr);
    
//     memset((void *)&serv_addr, 0, send_addr_len);
    

//     serv_addr.sin_family = AF_INET;
    
//     serv_addr.sin_port = htons(123); // NTP 服务器的端口号是 123
    
//     inet_pton(AF_INET, "120.25.115.20", &(serv_addr.sin_addr));
    


//     // 构造 NTP 请求数据包
//     memset(send_buf, 0, sizeof(send_buf));
    
//     send_buf[0] = 0x1b;
    

//     // while(1){
        
//         //发送NTP请求包
//         n = sendto(sockfd, send_buf, sizeof(send_buf), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
//         if (n < 0) {
//             printf("sendto failed\n");
//         }
        
//         // 接收NTP服务器响应
//         n = recvfrom(sockfd, recv_buf, sizeof(recv_buf), 0, NULL, NULL);
        
//         /* 获取时间 */
//         uint32_t result = 0;
        
//         for (int i = 40; i <= 43; i++) {
//             result = (result << 8) | recv_buf[i];
//         }
        
//         result -= (uint32_t)2208988800; //获取时间戳
        
//         time_t timestamp = result; // 时间戳值
        
//         time_t bj_timestamp = timestamp + 8 * 3600;  // 计算北京时间戳
        
//         // 将北京时间戳转换为北京时间
//        struct tm *bj_time = gmtime(&bj_timestamp);
       
//         date1.m_t.tm_year = bj_time->tm_year + 1900;
//         date1.m_t.tm_mon = bj_time->tm_mon + 1;
//         date1.m_t.tm_mday = bj_time->tm_mday;
//         date1.m_t.tm_hour = bj_time->tm_hour;
//         date1.m_t.tm_min = bj_time->tm_min;
//         date1.m_t.tm_sec = bj_time->tm_sec;
//         now = date1.m_t.tm_hour;
//         sprintf(date1.time,"%d-%02d-%02d %02d:%02d:%02d\n", date1.m_t.tm_year,date1.m_t.tm_mon,date1.m_t.tm_mday,
//                 date1.m_t.tm_hour, date1.m_t.tm_min, date1.m_t.tm_sec);
//         printf("%s\n",date1.time);
        
        

//         //free(bj_time);  // 释放内存
        
//         //获取当前时间
//         if(last == -1 || abs(now - last) >= 1){
//             last = now;
//             // get_weather(&my_weather);
//         }
        
//         sleep(15);
//     // }
//     close(sockfd);

// }


 


void uart_process()
{
    
    uint8_t str[]={0x01,0x03,0x00,0x01,0x00,0x01,0xd5,0xca};
    uint32_t date_hex;
    
    /*土壤温度数据（可放进结构体里）*/
    double soil_temperature;
    
    char a[20];
    int recv_length;
    uint8_t recv_buffer[STRING_MAXSIZE];
    unsigned int ret;
    UartAttribute attr;
   
    /*数据帧格式*/
    attr.baudRate = 9600;
    attr.dataBits = UART_DATA_BIT_8;
    attr.pad = FLOW_CTRL_NONE;
    attr.parity = UART_PARITY_NONE;
    attr.rxBlock = UART_BLOCK_STATE_NONE_BLOCK;
    attr.stopBits = UART_STOP_BIT_1;
    attr.txBlock = UART_BLOCK_STATE_NONE_BLOCK;
    PinctrlSet(GPIO0_PB6, MUX_FUNC2, PULL_KEEP, DRIVE_LEVEL2);
    PinctrlSet(GPIO0_PB7, MUX_FUNC2, PULL_UP, DRIVE_LEVEL2);

    while(flag==0 )
    {
        sleep(3);
        printf("uart wait 3s\n");
    }

    
    /*初始化*/
    ret = LzUartInit(UART_ID, &attr);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %d: LzUartInit(%d) failed!\n", __FILE__, __LINE__, ret);
        return;
    }

    LOS_Msleep(1000);

    while (1)
    {
        // LzUartWrite是异步发送，非阻塞发送,发送获取温度命令
        LzUartWrite(UART_ID, str, 8);
       
        recv_length = LzUartRead(UART_ID, recv_buffer, STRING_MAXSIZE);

	/*提取有效十六进制数据,*/
	date_hex=(recv_buffer[3]<<8)|(recv_buffer[4]);		
	
	/*转化为十进制double型数据*/
	sprintf(a,"%d",date_hex);
	soil_temperature=atof(a);
	soil_temperature=soil_temperature/10.0;
	sprintf(id.soil_temperature,"%.2f℃",soil_temperature);
	
        LOS_Msleep(4000);
    }
    
    return;
}


//主函数
void iot_cloud_ia_example()
{
    unsigned int ret = LOS_OK;
    unsigned int thread_id1;
    unsigned int thread_id2;
    unsigned int thread_id3;
    unsigned int thread_id4;
    unsigned int thread_id5;
    unsigned int thread_id6;
    TSK_INIT_PARAM_S task1 = {0};
    TSK_INIT_PARAM_S task2 = {0};
    TSK_INIT_PARAM_S task3 = {0};
    TSK_INIT_PARAM_S task4 = {0};
    TSK_INIT_PARAM_S task5 = {0};
    TSK_INIT_PARAM_S task6 = {0};

    ret = LOS_QueueCreate("queue", MSG_QUEUE_LENGTH, &m_ia_MsgQueue, 0, BUFFER_LEN);
    if (ret != LOS_OK)
    {
        printf("Falied to create Message Queue ret:0x%x\n", ret);
        return;
    }

    task1.pfnTaskEntry = (TSK_ENTRY_FUNC)iot_cloud_ia_thread;
    task1.uwStackSize = 4096;
    task1.pcName = "iot_cloud_ia_thread";
    task1.usTaskPrio = 24;
    ret = LOS_TaskCreate(&thread_id1, &task1);
    if (ret != LOS_OK)
    {
        printf("Falied to create iot_cloud_ia_thread ret:0x%x\n", ret);
        return;
    }

    task2.pfnTaskEntry = (TSK_ENTRY_FUNC)e53_ia_thread;
    task2.uwStackSize = 15000;
    task2.pcName = "e53_ia_thread";
    task2.usTaskPrio = 25;
    ret = LOS_TaskCreate(&thread_id2, &task2);
    if (ret != LOS_OK)
    {
        printf("Falied to create e53_ia_thread ret:0x%x\n", ret);
        return;
    }

    // task3.pfnTaskEntry = (TSK_ENTRY_FUNC)get_weather;
    // task3.uwStackSize = 4096;
    // task3.pcName = "get_weather";
    // task3.usTaskPrio = 26;
    // ret = LOS_TaskCreate(&thread_id3, &task3);
    // if (ret != LOS_OK)
    // {
    //     printf("Falied to create get_weather ret:0x%x\n", ret);
    //     return;
    // }

    task4.pfnTaskEntry = (TSK_ENTRY_FUNC)adc_process;
    task4.uwStackSize = 10240;
    task4.pcName = "adc_process";
    task4.usTaskPrio = 27;
    ret = LOS_TaskCreate(&thread_id4, &task4);
    if (ret != LOS_OK)
    {
        printf("Falied to create adc_process ret:0x%x\n", ret);
        return;
    }

    task5.pfnTaskEntry = (TSK_ENTRY_FUNC)gpio_process;
    task5.uwStackSize = 4096;
    task5.pcName = "gpio_process";
    task5.usTaskPrio = 28;
    ret = LOS_TaskCreate(&thread_id5, &task5);
    if (ret != LOS_OK)
    {
        printf("Falied to create gpio_process ret:0x%x\n", ret);
        return;
    }

    task6.pfnTaskEntry = (TSK_ENTRY_FUNC)uart_process;
    task6.uwStackSize = 2048;
    task6.pcName = "uart_process";
    task6.usTaskPrio = 29;
    ret = LOS_TaskCreate(&thread_id6, &task6);
    if (ret != LOS_OK)
    {
        printf("Falied to create uart_process ret:0x%x\n", ret);
        return;
    }


}

APP_FEATURE_INIT(iot_cloud_ia_example);